import { cloneDeep } from "lodash";
import { DataSourceTypeEnum, DataSourceTypeByDateEnum } from "@src/globalData/enum";
import { methodConfig } from "./config";
import { yunNao } from "@src/api/yunNao";
import { spotMarket } from "@src/api/spotMarket";
import {
  dataCategory,
  sendParamsStructure,
  dataCategoryLength,
  yunNaoAccount,
  getDefaultDataBaseData,
} from "./constant";
import dayjs from "dayjs";
import { encrypt, getDataFromLocalStorage, saveDataToLocalStorage } from "@src/utils/common";

/**调用云脑接口存储的数据结构 */
let sendParam: { [key: string]: any } = cloneDeep(sendParamsStructure);
/**每个类型的请求数据的接口数量 */
let typeNum: any = {};

/**处理数据的总入口，总方法
 * @dataType  数据类型
 * @dataSource 数据源
 * @date  日期
 */
export const processingDataFormat = async (
  dataType: DataSourceTypeEnum,
  dataSource: any,
  date: string
) => {
  let result = {};
  /**有爬取到值才进入数据转换，否则默认为空对象 */
  if (Object.keys(dataSource).length > 0) {
    result = await methodConfig[dataType].method(
      dataSource,
      date,
      methodConfig[dataType] as any
    );
  } else {
    result = {
      [dataType]: {},
    };
  }
  classifyData(result);
};

/**对爬取的数据进行分类，生成云脑接口入参格式数据
 * 然后计算每个分类请求数量是否一致，
 * 请求量数已达到就开始分类存储数据
 */
const classifyData = (formatData: any) => {
  const typeKey: any = Object.keys(formatData)[0];
  if (dataCategory[DataSourceTypeByDateEnum.D_REDUCE_DATE].includes(typeKey)) {
    sendParam[DataSourceTypeByDateEnum.D_REDUCE_DATE].data[0].data = Object.assign(
      sendParam[DataSourceTypeByDateEnum.D_REDUCE_DATE].data[0].data,
      { [typeKey]: formatData[typeKey] }
    );
    sendParam[DataSourceTypeByDateEnum.D_REDUCE_DATE].data[0].business_time = formatData.date;
    saveWebSpiderData(DataSourceTypeByDateEnum.D_REDUCE_DATE);
  } else if (dataCategory[DataSourceTypeByDateEnum.D_DATE].includes(typeKey)) {
    sendParam[DataSourceTypeByDateEnum.D_DATE].data[0].data = Object.assign(
      sendParam[DataSourceTypeByDateEnum.D_DATE].data[0].data,
      { [typeKey]: formatData[typeKey] }
    );
    sendParam[DataSourceTypeByDateEnum.D_DATE].data[0].business_time = formatData.date;
    saveWebSpiderData(DataSourceTypeByDateEnum.D_DATE);
  } else if (dataCategory.d_add_date.includes(typeKey)) {
    sendParam[DataSourceTypeByDateEnum.D_ADD_DATE].data[0].data = Object.assign(
      sendParam[DataSourceTypeByDateEnum.D_ADD_DATE].data[0].data,
      { [typeKey]: formatData[typeKey] }
    );
    sendParam[DataSourceTypeByDateEnum.D_ADD_DATE].data[0].business_time = formatData.date;
    saveWebSpiderData(DataSourceTypeByDateEnum.D_ADD_DATE);
  }
};


/**
 * 判断每个类型的数量是否达到
 * 调用云脑接口存储数据  通过云脑接口调用数据组数据，最终将数据存储到数组组数据库
 */
const saveWebSpiderData = async (type: string) => {
  /**如果爬取的对应数量类型达到每个类型的统计数量就开始调用云脑接口存储数据 */
  if (Object.keys(sendParam[type].data[0].data).length === typeNum[type]) {
    /**没有爬取时间的不往下执行 */
    if (!sendParam[type].data[0].business_time) return;

    try {
      const saveData = JSON.parse(JSON.stringify(sendParam[type]))

      /**置空已调用存储接口的类型数据，重新开始爬取存储 */
      console.log('存储原数据：', JSON.parse(JSON.stringify(sendParam[type].data)))
      sendParam[type].data = getDefaultDataBaseData()

      const {haveData, saveDataFilter} = sendParamFilterData(saveData.data[0].data)
      if(!haveData) {
        console.log('无数据，不存')
        return Promise.resolve()
      }
      saveData.data[0].data = saveDataFilter

      console.log('存储数据：', saveData)
      await yunNao.datapreservation([saveData]);
      console.log("获取数据存储成功", dayjs().format("YYYY-MM-DD HH:mm:ss"));
    } catch (error) {
      console.error("获取数据存储失败: ", error);
    }
  }
};

/**
 * 计算 n-1 n n+1 三种类型的接口数量 用于判断哪个类型请求完了
 * @params spotMarket 所有爬取的数据源类型key集合
 * */
export const getDataCategoryNum = (spotMarket: string[]) => {
  typeNum = cloneDeep(dataCategoryLength);
  spotMarket.forEach((item: any) => {
    if (dataCategory[DataSourceTypeByDateEnum.D_REDUCE_DATE].includes(item)) {
      typeNum[DataSourceTypeByDateEnum.D_REDUCE_DATE] += 1;
    } else if (dataCategory[DataSourceTypeByDateEnum.D_DATE].includes(item)) {
      typeNum[DataSourceTypeByDateEnum.D_DATE] += 1;
    } else if (dataCategory[DataSourceTypeByDateEnum.D_ADD_DATE].includes(item)) {
      typeNum[DataSourceTypeByDateEnum.D_ADD_DATE] += 1;
    }
  });
  return typeNum;
};

/**云脑登录 */
const yunNaoLogin = async () => {
  /**本地没有存储token,要先登录获取token然后再去掉云脑获取数据 */
  const token = await getDataFromLocalStorage("access_token");
    if (!token) {
      try {
        const res = await yunNao.login({
          encryptData: encrypt(yunNaoAccount),
          encryptLogin: true,
        });
        saveDataToLocalStorage(res.access_token, "access_token");
      } catch (error) {
        console.log("error: ", error);
      }
    }
}

/**插件初始化加载数据需要做的事情 */
export const initDataDul = async () => {
  console.log('--------------数据初始化-----------环境：',import.meta.env.VITE_APP_ENV)
  /**获取三个类型的接口请求数量 */
  getDataCategoryNum(Object.keys(spotMarket));
  /**云脑登录 */
  await yunNaoLogin()
}

export const sendParamFilterData = (originData: Record<string, Record<any,any>[] | Record<any,any>>) => {
  let haveData = false

  const saveDataFilter:Record<string, Record<any,any>[] | Record<any,any>> = {}

  for(let key in originData) {
    const dataList:any[] = []
    const originDataList = originData[key]

    if(originDataList instanceof Array) {
      if(!originData?.[key].length) continue
      originDataList.map(item => {
        const itemVal = cloneDeep(item)
        delete itemVal.oriRunDate
        delete itemVal.runDate
        
        delete itemVal.cityName
        delete itemVal.nodeId
        delete itemVal.nodeName
        dataList.push(...Object.values(itemVal))
      })
    } else {
      const itemVal = cloneDeep(originDataList)
      delete itemVal.oriRunDate
      delete itemVal.runDate
      dataList.push(...Object.values(itemVal))
    }


    const _haveData = dataList.some(val =>{
      if(typeof val === 'number') return true
      return !!val
    })
    if(!_haveData) continue

    haveData = true
    saveDataFilter[key] = originDataList
  }

  return {
    haveData,
    saveDataFilter
  }
}